// #include <iostream>
// // #include <thread>
// #include <pthread.h>
// #include <cstring>
// #include <cerrno>
// #include <unistd.h>
// using namespace std;
#include <vector>
#include "MyThread.hpp"
#include <unistd.h>
using namespace MyThread;

int g_tickets = 10000; // 共享资源，没有保护
// pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;
class LockGuard
{
public:
LockGuard(pthread_mutex_t* pmutex):_mutex(*pmutex)
{
    pthread_mutex_lock(&_mutex);
}
~LockGuard()
{
    pthread_mutex_unlock(&_mutex);
}

private:
pthread_mutex_t _mutex;
};
class ThreadData
{
public:
    ThreadData(const string &name, int &tickets, pthread_mutex_t &mutex) : _name(name), _tickets(tickets), _total(0), _mutex(mutex) {}

    const string _name;
    int &_tickets;
    int _total;
    pthread_mutex_t &_mutex;
};

// void Grabtickets(ThreadData &td)
// {
//     while (1)
//     {
//         // pthread_mutex_lock(&gmutex);//加锁
//         pthread_mutex_lock(&td._mutex);
//         if (td._tickets > 0)
//         {
//             usleep(1000);
//             cout << td._name << "get ticket:" << td._tickets << endl;
//             td._tickets--;
//             td._total++;
//             // pthread_mutex_unlock(&gmutex);//解锁
//             pthread_mutex_unlock(&td._mutex);
//         }
//         else
//         {
//             // pthread_mutex_unlock(&gmutex);//解锁
//             pthread_mutex_unlock(&td._mutex);
//             break;
//         }
//     }
// }

void Grabtickets(ThreadData &td)
{
    while (1)
    {
        LockGuard guard(&td._mutex);
        if (td._tickets > 0)
        {
            usleep(1000);
            cout << td._name << "get ticket:" << td._tickets << endl;
            td._tickets--;
            td._total++;
        }
        else
        {
            break;
        }
    }
}
int main()
{
    vector<Thread<ThreadData>> threads;
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, nullptr);
    for (int i = 1; i <= 4; i++)
    {
        string name = "thread-" + to_string(i);
        ThreadData td(name, g_tickets, mutex);
        threads.emplace_back(Grabtickets, td);
    }
    for (auto &e : threads)
    {
        e.start();
    }
    for (auto &e : threads)
    {
        e.join();
        cout << "wait thread done,thread is:" << e.dataaddress()->_name << " get total: " << e.dataaddress()->_total << endl;
    }
    pthread_mutex_destroy(&mutex);

    return 0;
}

// void print(const int& a)
// {
//     cout<<"a= "<<a<<endl;
// }
// int main()
// {
//     vector<Thread<int>>threads;
//     for(int i=1;i<=10;i++)//创建一批线程
//     {
//         string name="thread-"+to_string(i);
//         threads.emplace_back(print,10,name);
//     }
//     for(auto&e:threads)//启动一批线程
//     {
//         e.start();
//     }
//     for(auto&e:threads)//等待一批线程
//     {
//         e.join();
//         cout<<"wait thread done,thread is:"<<e.name()<<endl;
//     }

//     return 0;
// }

// void print(int&a)
// {
//     cout<<a<<endl;
// }
// int main()
// {
//     // print(10);
//     const string& str="abcdef";

//     string s2("afadfa");

//     return 0;
// }

// __thread int g_val = 100;
// void *newthreadrun1(void *args)
// {
//     int cnt = 5;
//     while (cnt--)
//         cout << "I am thread1, g_val: " << g_val-- << endl;
//     return nullptr;
// }
// void *newthreadrun2(void *args)
// {
//     int cnt = 5;
//     while (cnt--)
//         cout << "I am thread2, g_val: " << g_val << endl;
//     return nullptr;
// }
// int main()
// {
//     pthread_t tid1;
//     pthread_t tid2;

//     pthread_create(&tid1, nullptr, newthreadrun1, nullptr);
//     pthread_create(&tid2, nullptr, newthreadrun2, nullptr);

//     pthread_join(tid1, nullptr);
//     pthread_join(tid2, nullptr);

//     return 0;
// }

// void threadrun(int a, int b)
// {
//     int cnt = 5;
//     while (cnt--)
//     {
//         cout << "a+b=: " << a + b << endl;
//         sleep(1);
//     }
// }
// int main()
// {
//     thread t1(threadrun, 10, 20);
//     cout << "I am main thread" << endl;
//     t1.join();
//     return 0;
// }

// #include <iostream>
// #include <string>
// #include <vector>
// #include <functional>

// #include <pthread.h>
// #include <unistd.h>
// #include <sys/types.h>

// using namespace std;
// template <class T>
// T add(T x, T y)
// {
//     return x + y;
// }
// template <class T>
// class threaddata
// {
// public:
//     threaddata(const char *str, function<T(T, T)> task)
//         : _name(str), _task(task)
//     {
//         delete[] str;
//     }
//     T Dotask(T x, T y)
//     {
//         return _task(x, y);
//     }
//     string _name;
//     function<T(T, T)> _task;
//     T _result;
// };

// void *newthreadrun(void *args)
// {
//     threaddata<int> *p = (threaddata<int> *)args;
//     p->_result = p->Dotask(10, 20);
//     cout << p->_name << " get result: " << p->_result << endl;
//     delete p;
//     return nullptr;
// }

// int main()
// {
//     int a = 10;

//     int *p = &a;
//     char *c = static_cast<char *>(p);

//     void *p1 = &a;
//     char *c1 = static_cast<char *>(p1);

//     // pthread_t tid;
//     // vector<pthread_t> f;
//     // for (int i = 1; i <= 5; i++)
//     // {
//     //     char *buffer = new char[64];
//     //     snprintf(buffer, 64, "pthread-%d", i);
//     //     threaddata<int> *ptd = new threaddata<int>(buffer, add<int>);
//     //     pthread_create(&tid, nullptr, newthreadrun, ptd);
//     //     f.push_back(tid);
//     // }
//     // for (auto e : f)
//     // {
//     //     pthread_join(e, nullptr);
//     // }
//     return 0;
// }
// void *newthreadrun(void *args)
// {
//     char *str = (char *)args;
//     int cnt=5;
//     while(cnt--)
//     {
//         cout << str << " is running " << endl;
//         sleep(1);
//     }
//     delete[] str;//new[]的空间要delete[]
//     return nullptr;
// }
// int main()
// {
//     pthread_t tid;
//     vector<pthread_t>f;
//     for (int i = 1; i <= 5; i++)
//     {
//         char*buffer=new char[64];//这里必须new，否则五个线程看到的是一块空间
//         snprintf(buffer, 64, "pthread-%d", i);//不能用sizeof，因为sizeof(buffer)==8
//         pthread_create(&tid, nullptr, newthreadrun, buffer);
//         f.push_back(tid);
//     }
//     for(auto e:f)
//     {
//         pthread_join(e,nullptr);
//     }

//     return 0;
// }

// int g_val = 100;
// void *newthreadrun(void *args)
// {
//     char *str = (char *)args;
//     int cnt = 5;
//     while (cnt--)
//     {
//         cout << "new thread g_val is: " << g_val-- << endl;
//         sleep(1);
//     }
//     // pthread_exit((void*)12345);//这两种写法效果是一样的
//     return (void *)12345;
// }
// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, newthreadrun, (void *)"pthread-1");
//     sleep(2);
//     pthread_cancel(tid);
//     void *ret = nullptr;
//     int n = pthread_join(tid, &ret);
//     if (n == 0)
//     {
//         cout << " return val is: " << (long long)ret << endl;//ret==-1
//     }

// PTHREAD_CANCELED;

//     // int cnt1 = 5;
//     // while (cnt1--)
//     // {
//     //     cout<<"main thread g_val is: "<<g_val<<endl;
//     //     sleep(1);
//     // }
//     // void *ret = nullptr;
//     // int n = pthread_join(tid, &ret);
//     // if (n == 0)
//     // {
//     //     cout << " return val is: " << (long long)ret << endl;//指针64位下是8个字节，强转成long long不会损失精度
//     // }
//     return 0;
// }

// string ToHex(pthread_t id)
// {
//     char buffer[64];
//     snprintf(buffer,sizeof(buffer),"0x%lx",id);
//     return buffer;
// }
// void* newthreadrun(void*args)
// {
//     char*str=(char*)args;
//     while(1)
//     {
//         cout<<"I am new thread"<<" pid: "<<getpid()
//         <<" id: "<<ToHex(pthread_self())
//         <<" my name is: "<<str<<endl;
//         sleep(1);
//     }
// }
// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid,nullptr,newthreadrun,(void*)"pthread-1");
//     while(1)
//     {
//         cout<<"I am main thread"<<" pid: "<<getpid()<<" tid: "<<ToHex(tid)<<endl;
//         sleep(1);
//     }

//     return 0;
// }